import {dbAsyncStorage} from '@/module/storage'
// 定义

export interface DbDoc {
  _id: string,
  _rev?: string,

  [key: string]: any
}

// --------------------------------------- 基础对象 ---------------------------------------

export interface DbList<T> {

  list: Array<T>;

  rev?: string;

}

export interface DbRecord<T> {

  record: T;

  rev?: string;

}

// --------------------------------------- 列表操作 ---------------------------------------

export async function listByAsync<T>(key: string): Promise<DbList<T>> {
  const res = await dbAsyncStorage.get(key);
  if (res) {
    return {
      list: res.value,
      rev: res._rev
    };
  }
  return {list: []};
}

export async function saveListByAsync<T>(key: string, records: Array<T>, rev?: string): Promise<undefined | string> {
  const res = await dbAsyncStorage.put({
    _id: key,
    _rev: rev,
    value: toRaw(records)
  });
  if (res.error) {
    if (res.message === "Document update conflict") {
      // 查询后更新
      const res = await dbAsyncStorage.get(key);
      return await saveListByAsync(key, records, res ? res._rev : undefined);
    }
    return Promise.reject(res.message);
  }
  return Promise.resolve(res.rev);
}


// --------------------------------------- 单一对象操作 ---------------------------------------

export async function getFromOne<T = any>(key: string): Promise<DbRecord<T> | null> {
  const res = await dbAsyncStorage.get(key);
  if (!res) {
    return null;
  }
  return Promise.resolve({
    record: res.value,
    rev: res._rev
  });
}

export async function getFromOneByAsync<T extends Record<string, any>>(key: string): Promise<DbRecord<T | null>> {
  const res = await dbAsyncStorage.get(key);
  if (!res) {
    return {record: null}
  }
  return Promise.resolve({
    record: res.value,
    rev: res._rev
  });
}

export async function getFromOneDefaultByAsync<T extends Record<string, any>>(key: string, record: T): Promise<DbRecord<T>> {
  const res = await dbAsyncStorage.get(key);
  if (!res) {
    return {record}
  }
  return Promise.resolve({
    record: Object.assign(record, res.value),
    rev: res._rev
  });
}

export async function saveOneByAsync<T>(key: string, value: T, rev?: string): Promise<undefined | string> {
  const res = await dbAsyncStorage.put({
    _id: key,
    _rev: rev,
    value: toRaw(value)
  });
  if (res.error) {
    if (res.message === "Document update conflict") {
      // 查询后更新
      const res = await dbAsyncStorage.get(key);
      return await saveOneByAsync(key, value, res ? res._rev : undefined);
    }
    return Promise.reject(res.message);
  }
  return Promise.resolve(res.rev);
}

export async function removeOneByAsync(key: string, ignoreError: boolean = false): Promise<void> {
  const res = await dbAsyncStorage.remove(key);
  if (res.error) {
    if (!ignoreError) {
      return Promise.reject(res.message);
    }
  }
}

